package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import com.example.xcService.pojo.tool.HttpTool;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

/*
* 作业帮
* */
@Slf4j
public class Plugin_ECARD_P046 implements ChannelService {

    @Override
    public ChannelResult QueryBalance(JSONObject apiConfig) {
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }
    /**
     * 	productId	Number	是	充值产品类型，需单独申请
     * 	partnerId	String	是	合作方标识，需单独申请
     * 	partnerOrderId	String	是	合作方订单Id，须保证在合作方内部的唯一性（接口支持幂等调用）
     * 	user	String	是	用户标识，当userType为phone时表示手机号，为uid时表示加密用户id，为rawUid时表示原始用户id
     * 	userType	String	是	用户标识类型，可选值：phone或uid或rawUid。当值为phone时，如果用户不存在将会自动注册
     * 	ts	Number	是	当前秒级时间戳，例如：
     *      1556161379
     * 	sign	String	是	参数签名，签名算法详见“签名算法”
     * @param apiConfig
     * @param data
     * @return
     */
    // 提交订单
    @Override
    public ChannelResult Submit(JSONObject apiConfig, Map<String, Object> data) {

        try {
            // 产品id
            String productId = String.valueOf(data.get("SUPProductId"));
            // 订单号
            String partnerOrderId = String.valueOf(data.get("ChannelOrderCode"));
            // 充值账户
            String user = String.valueOf(data.get("AccountVal"));

            if (!Pattern.matches("^1[3456789]\\d{9}$", user)) {
                return  ChannelResult.FAILED("手机号码异常");
            }
            // 合作方标识
            String partnerId = apiConfig.getString("partnerId");
            HashMap<String, Object> params = new HashMap<>();
            params.put("productId",productId);
            params.put("partnerOrderId", partnerOrderId);
            params.put("user", user);
            params.put("partnerId", partnerId);
            params.put("userType", "phone");
            long ts = System.currentTimeMillis()/1000;
            params.put("ts",ts);//时间戳

            String secret = apiConfig.getString("secret");

            String sign = generateSign(params, secret);
            params.put("sign",sign);

            // 测试 https://apivip-dav-z.suanshubang.com 正式 https://apivip.zuoyebang.com
            String submitUrl = String.valueOf(apiConfig.get("SubmitUrl"));

            JSONObject res = JSONObject.parseObject(HttpTool.HttpPost2(submitUrl, params));
            String errNo = res.getString("errNo");
            String errstr = res.getString("errstr");
            // 0 成功,
            if ("0".equals(errNo)){
                return ChannelResult.IN_PROCESS("充值中");
            } else if ("15".equals(errNo) || "10000".equals(errNo) || "90602".equals(errNo) || "90603".equals(errNo) || "90505".equals(errNo) ||
                     "90516".equals(errNo)|| "90600".equals(errNo)|| "90601".equals(errNo)|| "90604".equals(errNo)|| "99904".equals(errNo)||
                    "1".equals(errNo)) {
                // 15 内部系统错误(直接重试) 10000	用户尚未注册(直接重试) 90602 请求失效(ts参数过期,调整后重试) 90603 签名失效(调整签名参数后重试)
                // 90505	用户充值总次数达到最大值(联系zyb处理，调整配置重试，默认不限制)
                // 90516	用户充值总时长超过最大值(联系zyb处理，调整配置重试，默认不限制)
                // 90600	用户当日达到最大充值次数(联系zyb处理，调整配置重试，默认不限制)
                // 90601	合作方当日达到最大充值次数(联系zyb处理，调整配置重试，默认不限制)
                // 90604	单个商品达到最大充值次数(联系zyb处理，调整配置重试，默认不限制)
                // 99904	IP限制禁止访问 (ip不在zyb白名单列表里面,新增出口ip需要同步zyb)
                // 1	参数错误(调整参数后重试)
                return ChannelResult.error(errstr);
            } else {
                return ChannelResult.FAILED(errstr);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("作业帮提交订单接口错误：",e);
            return ChannelResult.error("作业帮提交订单接口错误");
        }
    }

    @Override
    public ChannelResult Query(JSONObject apiConfig, Map<String, Object> data) {

        try {
            // 类型
            String ChannelOrderCode = String.valueOf(data.get("ChannelOrderCode"));
            String partnerOrderId = apiConfig.getString("partnerOrderId");

            HashMap<String, Object> params = new HashMap<>();
            params.put("partnerId",partnerOrderId);//
            params.put("partnerOrderId",ChannelOrderCode);//
            long ts = System.currentTimeMillis()/1000;
            params.put("ts",ts);//时间戳

            String secret = apiConfig.getString("secret");

            String sign = generateSign(params, secret);
            params.put("sign",sign);

            String QueryUrl = String.valueOf(apiConfig.get("QueryUrl"));

            JSONObject res = JSONObject.parseObject(HttpTool.HttpPost2(QueryUrl, params));
            String errNo = res.getString("errNo");
            String errstr = res.getString("errstr");
            if ("0".equals(errNo)){
                JSONObject data1 = res.getJSONObject("data");
                if (data1 != null){
                    //1-充值成功，2-充值失败，3-处理中，4-已退订
                    String tradeStatus = data1.getString("tradeStatus");
                    if ("1".equals(tradeStatus)){
                        return ChannelResult.success("充值成功");
                    } else if ("2".equals(tradeStatus) || "4".equals(tradeStatus) ) {
                        // 充值失败 已退订
                        return ChannelResult.FAILED(errstr);
                    } else if ("3".equals(tradeStatus)) {
                        return ChannelResult.IN_PROCESS("充值中");
                    } else {
                        return ChannelResult.error(errstr);
                    }
                } else {
                    return ChannelResult.error(errstr);
                }
            } else if ("70002".equals(errNo)) {
                // 订单不存在
                return ChannelResult.FAILED(errstr);
            } else {
                return ChannelResult.error(errstr);
            }

        }catch (Exception e){
            e.printStackTrace();
            log.error("作业帮查询订单接口错误：",e);
            return ChannelResult.error("作业帮查询订单接口错误");
        }
    }
    @Override
    public ChannelResult Notify(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");
    }

    // 基础md5加密
    public static String generateSign(Map<String, Object> params, String secret) throws NoSuchAlgorithmException {
        Set<String> keySet = params.keySet();
        String[] keyArray = keySet.toArray(new String[0]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keyArray.length; i++) {
            if (String.valueOf(params.get(keyArray[i])).length() > 0) {
                sb.append(keyArray[i]).append("=").append(params.get(keyArray[i])).append("&");
            }
        }
        sb.deleteCharAt(sb.length()-1);
        System.out.println(sb);
        byte[] digest = MessageDigest.getInstance("MD5").digest(sb.toString().getBytes(StandardCharsets.UTF_8));

        // Step 4: 将摘要结果转换为十六进制表示
        StringBuilder signBuilder = new StringBuilder();
        for (byte b : digest) {
            String hex = Integer.toHexString(b & 0xff);
            if (hex.length() == 1) {
                signBuilder.append("0");
            }
            signBuilder.append(hex);
        }
        String plainText = signBuilder.toString() + secret;
        System.out.println(plainText);
        byte[] digest2 = MessageDigest.getInstance("MD5").digest(plainText.getBytes(StandardCharsets.UTF_8));

        // Step 4: 将摘要结果转换为十六进制表示
        StringBuilder signBuilder2 = new StringBuilder();
        for (byte b : digest2) {
            String hex = Integer.toHexString(b & 0xff);
            if (hex.length() == 1) {
                signBuilder2.append("0");
            }
            signBuilder2.append(hex);
        }
        return signBuilder2.toString();
    }
}
